package com.ruoyi.training.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.training.domain.*;
import com.ruoyi.training.dto.payment.PaymentFormDto;
import com.ruoyi.training.dto.payment.PaymentInvoiceDto;
import com.ruoyi.training.dto.payment.PaymentRefundDto;
import com.ruoyi.training.dto.registration.RegistrationDto;
import com.ruoyi.training.mapper.*;
import com.ruoyi.training.util.xuehua.SnowflakeIdUtils;
import com.ruoyi.training.vo.payment.ChangePayVo;
import com.ruoyi.training.vo.payment.SelectPayVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.training.service.IPaymentRecordService;

/**
 * 缴费记录Service业务层处理
 *
 * @author hcc
 * @date 2025-09-28
 */
@Service
public class PaymentRecordServiceImpl implements IPaymentRecordService
{
    @Autowired
    private PaymentRecordMapper paymentRecordMapper;

    @Autowired
    private InvoiceMapper invoiceMapper;

    @Autowired
    private RegistrationMapper registrationMapper;

    @Autowired
    private UnitsMapper unitsMapper;

    @Autowired
    private StudentsMapper studentsMapper;

    @Autowired
    private RemarksMapper remarksMapper;

    @Autowired
    private TrainingClassMapper trainingClassMapper;
    /**
     * 查询缴费记录
     *
     * @param paymentRecordId 缴费记录主键
     * @return 缴费记录
     */
    @Override
    public PaymentRecord selectPaymentRecordByPaymentRecordId(String paymentRecordId)
    {
        return paymentRecordMapper.selectPaymentRecordByPaymentRecordId(paymentRecordId);
    }

    /**
     * 查询缴费记录列表
     *
     * @param paymentRecord 缴费记录
     * @return 缴费记录
     */
    @Override
    public List<PaymentRecord> selectPaymentRecordList(PaymentRecord paymentRecord)
    {
        return paymentRecordMapper.selectPaymentRecordList(paymentRecord);
    }

    /**
     * 新增缴费记录
     *
     * @param paymentRecord 缴费记录
     * @return 结果
     */
    @Override
    public int insertPaymentRecord(PaymentRecord paymentRecord)
    {
        paymentRecord.setPaymentRecordId(String.valueOf(new SnowflakeIdUtils(5,8).nextId()));
        paymentRecord.setCreateTime(DateUtils.getNowDate());
        paymentRecord.setPaymentState("1");
        paymentRecord.setPaymentTime(DateUtils.getNowDate());
        if (!"".equals(paymentRecord.getPaymentVoucher())){
            paymentRecord.setVoucherUploadTime(DateUtils.getNowDate());
        }

        Invoice invoice = new Invoice();
        invoice.setInvoiceId(String.valueOf(new SnowflakeIdUtils(5,8).nextId()));
        invoice.setPaymentRecordId(paymentRecord.getPaymentRecordId());
        invoice.setInvoiceAmount(paymentRecord.getPaymentAmount());
        invoice.setInvoiceCategory("1");
        invoice.setInvoiceStatus("1");
        invoice.setInvoiceType("1");
        invoice.setCreateBy(SecurityUtils.getUsername());
        invoice.setCreateTime(DateUtils.getNowDate());
        invoiceMapper.insertInvoice(invoice);
        return paymentRecordMapper.insertPaymentRecord(paymentRecord);
    }

    /**
     * 修改缴费记录
     *
     * @param paymentRecord 缴费记录
     * @return 结果
     */
    @Override
    public int updatePaymentRecord(PaymentRecord paymentRecord)
    {
        paymentRecord.setUpdateTime(DateUtils.getNowDate());
        return paymentRecordMapper.updatePaymentRecord(paymentRecord);
    }

    /**
     * 批量删除缴费记录
     *
     * @param paymentRecordIds 需要删除的缴费记录主键
     * @return 结果
     */
    @Override
    public int deletePaymentRecordByPaymentRecordIds(String[] paymentRecordIds)
    {
        return paymentRecordMapper.deletePaymentRecordByPaymentRecordIds(paymentRecordIds);
    }

    /**
     * 删除缴费记录信息
     *
     * @param paymentRecordId 缴费记录主键
     * @return 结果
     */
    @Override
    public int deletePaymentRecordByPaymentRecordId(String paymentRecordId)
    {
        return paymentRecordMapper.deletePaymentRecordByPaymentRecordId(paymentRecordId);
    }

    /**
     * 修改缴费
     */
    @Override
    public int changePay(ChangePayVo changePayVo) {
        String[] paymentRecordIds = changePayVo.getPaymentRecordIds();
        int result = 0;
        for (String paymentRecordId : paymentRecordIds) {
            PaymentRecord paymentRecord = paymentRecordMapper.selectPaymentRecordByPaymentRecordId(paymentRecordId);
            if (StringUtils.isNotNull(paymentRecord)){
                if (StringUtils.isNotEmpty(changePayVo.getPaymentMethod())){
                    paymentRecord.setPaymentMethod(changePayVo.getPaymentMethod());
                }
                if (StringUtils.isNotEmpty(changePayVo.getPaymentState())){
                    paymentRecord.setPaymentState(changePayVo.getPaymentState());
                }
                paymentRecord.setUpdateTime(DateUtils.getNowDate());
                paymentRecord.setUpdateBy(SecurityUtils.getUsername());
                result = paymentRecordMapper.updatePaymentRecord(paymentRecord);
            }
        }
        return result;
    }

    /**
     * 查询缴费记录列表
     */
    @Override
    public List<PaymentInvoiceDto> getPaymentRecordList(SelectPayVo selectPayVo) {
        // 1. 先查询符合条件的缴费记录ID列表（字符串类型ID）
        List<String> paymentRecordIds = paymentRecordMapper.selectPaymentIdsByCondition(selectPayVo);
        if (CollectionUtils.isEmpty(paymentRecordIds)) {
            return Collections.emptyList();
        }
        // 2. 批量查询符合条件的缴费记录
        List<PaymentRecord> paymentRecords = paymentRecordMapper.selectByIds(paymentRecordIds.toArray(new String[0]));
        if (CollectionUtils.isEmpty(paymentRecords)) {
            return Collections.emptyList();
        }

        // 3. 提取所有报名ID并去重（字符串类型）
        Set<String> registrationIdSet = new HashSet<>();
        for (PaymentRecord record : paymentRecords) {
            if (StringUtils.isNotEmpty(record.getRegistrationId())) {
                String[] split = record.getRegistrationId().split(",");
                Collections.addAll(registrationIdSet, split);
            }
        }
        // 4. 批量查询符合条件的报名表（带培训类别条件）
        List<RegistrationDto> registrations = registrationMapper.selectPayInvoiceList(new ArrayList<>(registrationIdSet), selectPayVo);
        // 按报名ID（字符串）分组缓存
        Map<String, RegistrationDto> registrationMap = registrations.stream()
                .collect(Collectors.toMap(RegistrationDto::getRegistrationId, r -> r));

        // 8. 批量查询符合条件的发票（带发票类型、状态和时间条件）
        List<Invoice> invoices = invoiceMapper.selectByPaymentRecordIdsAndConditions(
                paymentRecordIds,
                selectPayVo.getInvoiceType(),
                selectPayVo.getInvoiceStatus(),
                selectPayVo.getIssueStartTime(),
                selectPayVo.getIssueEndTime());
        Map<String, Invoice> invoiceMap = invoices.stream()
                .collect(Collectors.toMap(Invoice::getPaymentRecordId, i -> i));

        // 9. 组装结果
        List<PaymentInvoiceDto> paymentInvoiceDtoList = new ArrayList<>();
        for (PaymentRecord record : paymentRecords) {
            // 处理报名信息列表
            if (StringUtils.isNotEmpty(record.getRegistrationId())) {
                String[] registrationIds = record.getRegistrationId().split(",");
                for (String regId : registrationIds) {
                    if (StringUtils.isNotEmpty(regId)) {
                        PaymentInvoiceDto dto = new PaymentInvoiceDto();
                        BeanUtils.copyProperties(record, dto);
                        Remarks remarks = remarksMapper.selectRemarksByForeignId(record.getPaymentRecordId(), "2");
                        if (StringUtils.isNotNull(remarks)){
                            dto.setRemarks(remarks.getRemarks());
                        }
                        // 设置发票信息
                        Invoice invoice = invoiceMap.get(record.getPaymentRecordId());
                        if (invoice != null) {
                            dto.setInvoiceStatus(invoice.getInvoiceStatus());
                            dto.setInvoiceType(invoice.getInvoiceType());
                            dto.setInvoiceId(invoice.getInvoiceId());
                            dto.setInvoiceCategory(invoice.getInvoiceCategory());
                            dto.setInvoiceUnitName(invoice.getInvoiceUnitName());
                            dto.setInvoiceCreditCode(invoice.getInvoiceCreditCode());
                        }
                        RegistrationDto registration = registrationMap.get(regId.trim());
                        if (registration != null) {
                            BeanUtils.copyProperties(registration,dto);
                        }
                        paymentInvoiceDtoList.add(dto);
                    }
                }
            }
        }
        return paymentInvoiceDtoList;
    }

    /**
     * 获取缴费记录详细信息
     */
    @Override
    public PaymentFormDto selectByPaymentRecordId(String paymentRecordId) {
        PaymentFormDto paymentFormDto = new PaymentFormDto();
        Remarks remarks = remarksMapper.selectRemarksByForeignId(paymentRecordId, "2");
        if (StringUtils.isNotNull(remarks)){
            paymentFormDto.setExampleOne(remarks.getRemarks());
        }
        PaymentRecord paymentRecord = paymentRecordMapper.selectPaymentRecordByPaymentRecordId(paymentRecordId);
        if (StringUtils.isNotNull(paymentRecord)){
            BeanUtils.copyProperties(paymentRecord,paymentFormDto);
            String[] split = paymentRecord.getRegistrationId().split(",");
            List<RegistrationDto> registrationDtoList = new ArrayList<>();
            for (String registrationId : split) {
                RegistrationDto registrationDto = registrationMapper.selectRegistrationByRegistrationId(registrationId);
                if (StringUtils.isNotNull(registrationDto)){
                    if (StringUtils.isNotEmpty(registrationDto.getUnitId())){
                        Units units = unitsMapper.selectUnitsByUnitId(registrationDto.getUnitId());
                        paymentFormDto.setUnits(units);
                    }else {
                        Units units = new Units();
                        paymentFormDto.setUnits(units);
                    }
                    registrationDtoList.add(registrationDto);
                }
            }
            paymentFormDto.setRegistrationDtoList(registrationDtoList);
        }
        return paymentFormDto;
    }

    /**
     * 获取退费申请详细信息
     */
    @Override
    public PaymentRefundDto selectRefundInfo(String paymentRecordId) {
        PaymentRefundDto paymentRefundDto = new PaymentRefundDto();
        PaymentRecord paymentRecord = paymentRecordMapper.selectPaymentRecordByPaymentRecordId(paymentRecordId);
        BeanUtils.copyProperties(paymentRecord,paymentRefundDto);
        paymentRefundDto.setRefundPerson(SecurityUtils.getUsername());
        paymentRefundDto.setRefundTime(DateUtils.getNowDate());
        return paymentRefundDto;
    }

    /**
     * 获取我的缴费记录列表
     */
    @Override
    public List<PaymentInvoiceDto> myPaymentRecordList(SelectPayVo selectPayVo) {
        selectPayVo.setStudentId(SecurityUtils.getLoginUser().getSysUser().getStudentId());
        List<PaymentRecord> paymentRecords = paymentRecordMapper.selectPaymentList(selectPayVo);
        StringJoiner projectNames = new StringJoiner(";");
        StringJoiner classNames = new StringJoiner(";");
        StringJoiner feeNames = new StringJoiner(";");
        List<PaymentInvoiceDto> collect = paymentRecords.stream().map(paymentRecord -> {
            PaymentInvoiceDto paymentInvoiceDto = new PaymentInvoiceDto();
            Invoice invoice = invoiceMapper.selectInvoiceByPaymentRecordId(paymentRecord.getPaymentRecordId());
            BeanUtils.copyProperties(paymentRecord, paymentInvoiceDto);
            BeanUtils.copyProperties(invoice, paymentInvoiceDto);
            String[] split = paymentRecord.getRegistrationId().split(",");
            for (String registrationId : split) {
                RegistrationDto registrationDto = registrationMapper.selectRegistrationByRegistrationId(registrationId);
                TrainingClass trainingClass = trainingClassMapper.selectTrainingClassByTrainingClassId(registrationDto.getExampleThree());
                BeanUtils.copyProperties(registrationDto, paymentInvoiceDto);
                projectNames.add(registrationDto.getProjectMap());
                classNames.add(trainingClass.getTrainingClassName());
                feeNames.add(registrationDto.getProjectSum());
            }
            paymentInvoiceDto.setProjectMap(projectNames.toString());
            paymentInvoiceDto.setTrainingClass(classNames.toString());
            paymentInvoiceDto.setProjectSum(feeNames.toString());
            return paymentInvoiceDto;
        }).collect(Collectors.toList());
        return collect;
    }
}
